package com.frejoys.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.frejoys.common.dto.admin.AuthRuleAccessDeleteDto;
import com.frejoys.common.dto.admin.UserNameAndPhoneDto;
import com.frejoys.common.dto.common.auth.AuthGroupAccessListDto;
import com.frejoys.common.util.AppConfigUtil;
import com.frejoys.common.vo.admin.AuthRuleAccessListVo;
import com.frejoys.dao.entity.*;
import com.frejoys.dao.mapper.AuthGroupAccessMapper;
import com.frejoys.dao.mapper.AuthGroupMapper;
import com.frejoys.dao.mapper.UserMapper;
import com.frejoys.service.AuthGroupAccessService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service
@RequiredArgsConstructor
public class AuthGroupAccessServiceImpl extends ServiceImpl<AuthGroupAccessMapper, AuthGroupAccess> implements AuthGroupAccessService {

    private final UserMapper userMapper;

    private final AuthGroupMapper authGroupMapper;

    @Override
    public Boolean addInfo(Long userId, Integer groupId) {
        return save(new AuthGroupAccess(){{
            setUserId(userId);
            setGroupId(groupId);
        }});
    }

    @Override
    public Boolean deleteByUserId(Long userId){
        LambdaQueryWrapper<AuthGroupAccess> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AuthGroupAccess::getUserId,userId);
        return baseMapper.delete(queryWrapper)>0;
    }
    @Override
    public Boolean isSuperAdmin(Long userId) {
        return null;
    }

    @Override
    public List<AuthGroupAccess> getList(Long userId, AuthGroupAccessListDto dto) {
        return null;
    }

    @Override
    public List<AuthGroupAccess> getListByUserId(Long userId) {
        LambdaQueryWrapper<AuthGroupAccess> wrapper = new QueryWrapper().lambda();
        wrapper.eq(AuthGroupAccess::getUserId, userId);
        return list(wrapper);
    }

    @Override
    public List<AuthGroupAccess> getListByGroupId(Long groupId) {
        LambdaQueryWrapper<AuthGroupAccess> wrapper = new QueryWrapper().lambda();
        wrapper.eq(AuthGroupAccess::getGroupId, groupId);
        return list(wrapper);
    }


    @Override
    public IPage<AuthRuleAccessListVo> authRuleAccessList(UserNameAndPhoneDto dto) {
        Page page = new Page<>(dto.getPage(), dto.getSize());

        LambdaQueryWrapper<AuthGroupAccess> wrapper = new LambdaQueryWrapper();
        if (StrUtil.isNotEmpty(dto.getNickname())){
            List<Long> userIds = userMapper.nicknameByUserId(dto.getNickname());

            if (userIds.isEmpty()){
                return new Page<>();
            }
            wrapper.in(AuthGroupAccess::getUserId,userIds);
        }
        if (StrUtil.isNotEmpty(dto.getPhone())){
            Long userId = userMapper.phoneByUserId(dto.getPhone());

            if (userId == null){
                return new Page<>();
            }
            wrapper.eq(AuthGroupAccess::getUserId,userId);
        }

        Page<AuthGroupAccess> authGroupAccessPage = baseMapper.selectPage(page, wrapper);
        IPage<AuthRuleAccessListVo> listVoIPage = authGroupAccessPage.convert(authGroupAccess -> BeanUtil.copyProperties(authGroupAccess, AuthRuleAccessListVo.class));

        List<AuthRuleAccessListVo> list = listVoIPage.getRecords();

        if (!list.isEmpty()){

            //用户id
            List<Long> userIds = list.stream().map(AuthRuleAccessListVo::getUserId).toList();

            //组id
            List<Integer> groupId = list.stream().map(AuthRuleAccessListVo::getGroupId).toList();

            List<User> users = userMapper.getUserByIds(userIds);
            Map<Long, User> userMap = users.stream().collect(Collectors.toMap(User::getId, user -> user));

            List<AuthGroup> authGroups = authGroupMapper.getAuthGroupByIds(groupId);
            Map<Integer, AuthGroup> authGroupMap = authGroups.stream().collect(Collectors.toMap(AuthGroup::getId, authGroup -> authGroup));

            for (AuthRuleAccessListVo vo:list) {

                if (userMap.containsKey(vo.getUserId())){
                    User user = userMap.get(vo.getUserId());
                    vo.setNickname(user.getNickname());
                    vo.setPhone(user.getPhone());
                    vo.setAvatar(AppConfigUtil.getUrlPrefix(user.getAvatar()));
                }
                if (authGroupMap.containsKey(vo.getGroupId())){
                    vo.setGroupName(authGroupMap.get(vo.getGroupId()).getName());
                }
            }
        }
        return listVoIPage;
    }


    @Override
    public boolean authRuleAccessUpInfo(AuthRuleAccessDeleteDto dto) {
        LambdaQueryWrapper<AuthGroupAccess> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AuthGroupAccess::getUserId,dto.getUserId()).eq(AuthGroupAccess::getGroupId,dto.getGroupId());
        baseMapper.delete(wrapper);
        return true;
    }
}
